home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / server1.zip / _OBSERVE.QC < prev    next >
Text File  |  1996-09-07  |  14KB  |  407 lines

  1. /*
  2. **
  3. ** _observe.qc (Observer Code, 1.6)
  4. **
  5. ** Copyright (C) 1996 Johannes Plass
  6. ** 
  7. ** This program is free software; you can redistribute it and/or modify
  8. ** it under the terms of the GNU General Public License as published by
  9. ** the Free Software Foundation; either version 2 of the License, or
  10. ** (at your option) any later version.
  11. ** 
  12. ** This program is distributed in the hope that it will be useful,
  13. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ** GNU General Public License for more details.
  16. **
  17. ** You should have received a copy of the GNU General Public License
  18. ** along with this program; if not, write to the Free Software
  19. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ** 
  21. ** Author:   Johannes Plass (plass@dipmza.physik.uni-mainz.de)
  22. **
  23. */
  24.  
  25. void(entity player) ObserverSetPlayerPos;
  26. void(entity player,entity door) ObserverTeleportThroughDoor;
  27. void(entity player,entity tele) ObserverTeleportThroughTeleporter;
  28.  
  29. void(entity player) ObserverInfo =
  30. {
  31.    if (!USE_MODULE_OBSERVER) return;
  32.    sprint(player,"# Observer: Allows you to peep.\n");
  33.    sprint(player,"  Type 'help-observer' for help.\n");
  34. };
  35.  
  36. void(entity player) ObserverInit =
  37. {
  38.    if (!USE_MODULE_OBSERVER) return;
  39.    stuffcmd(player,"alias help-observer \"impulse 205\";\n");
  40.    stuffcmd(player,"alias observer-noclip \"impulse 206\";\n");
  41. };
  42.  
  43. void(entity player) ObserverHelp =
  44. {
  45.    if (!USE_MODULE_OBSERVER) return;
  46.  
  47. //                123456789#123456789#123456789#12345678
  48.    sprint(player,"# Observer: Allows to watch the\n");
  49.    sprint(player,"  ongoing madness.\n");
  50.    sprint(player,"  As observer you can:\n");
  51.    sprint(player,"    - fly around.\n");
  52.    sprint(player,"    - move to another watch-spot by \n");
  53.    sprint(player,"      pressing the fire-button. \n");
  54.    sprint(player,"    - join the game as regular player\n");
  55.    sprint(player,"      by pressing the jump-button. \n");
  56.    sprint(player,"  Use the command 'observer-noclip'\n");
  57.    sprint(player,"  to turn clipping on or off.\n");
  58.    sprint(player,"  Press the fire-button to become an\n");
  59.    sprint(player,"  observer when you are dead.\n");
  60. };
  61.  
  62. void () ObserverThink =
  63. {
  64.    //dprint("ObserverThink: executing\n");//#jp#(debug)
  65.  
  66.    if (!USE_MODULE_OBSERVER) return;
  67.  
  68.    self.weaponmodel = "";
  69.    self.weaponframe = 0;
  70.    //#jp# Hack to provide a decent flying velocity.
  71.    //#jp# Damn it, what a mess this quakec is.
  72.    self.flags = self.flags | FL_ONGROUND;
  73.  
  74.    { 
  75.       local float invcos,nv,nvp,nvpmax,nvs,nsp,sp,svz;
  76.       local vector f,vp,vs;
  77.  
  78.       svz = self.velocity_z * 0.75;
  79.       self.velocity_z = 0;
  80.  
  81.       // v_forward is already normalized
  82.       f_x = v_forward_x; 
  83.       f_y = v_forward_y; 
  84.       f_z = 0;
  85.       invcos = vlen(f); if (invcos) invcos= 1/invcos; else invcos=0;
  86.       f = f*invcos; // normalize f
  87.  
  88.       sp = f * self.velocity;
  89.       vp = sp*f;
  90.       nvp = vlen(vp); if (sp<0) nvp = nvp*(-1);
  91.       vs = self.velocity - vp;
  92.  
  93.       vp = v_forward * (nvp * invcos);
  94.       vp_z = vp_z + svz;
  95.       nvp = vlen(vp);
  96.       nvpmax = (320 - 100*(v_forward * '0 0 1'));
  97.       if (nvp > nvpmax) { vp = vp * (nvpmax/nvp); }
  98.  
  99.       self.velocity = vp + vs;
  100.    }
  101.  
  102.    {
  103.       local entity e;
  104.       local float cont;
  105.       e = findradius(self.origin,75);
  106.       if (e) { cont = TRUE;  }
  107.       else   { cont = FALSE; }
  108.       while (cont) {
  109.          // dprint(e.classname); dprint("\n");
  110.          if (e.classname == "door") {
  111.             ObserverTeleportThroughDoor(self,e);
  112.             cont = FALSE;
  113.          }
  114.          if (e.classname == "trigger_teleport") {
  115.             ObserverTeleportThroughTeleporter(self,e);
  116.             cont = FALSE;
  117.          }
  118.          e = e.chain;
  119.          if (!e) { cont = FALSE; }
  120.       }
  121.    }
  122.  
  123.    if (self.observer_status & OBSERVER_BECOME_OBSERVER) {
  124.       ObserverBecomeObserver(self);
  125.       return;
  126.    }
  127.  
  128.    if (self.observer_status & OBSERVER_NEXTVIEW) {
  129.       self.observer_pos_num = self.observer_pos_num + 1;
  130.       ObserverSetPlayerPos(self);
  131.       self.observer_status = self.observer_status - OBSERVER_NEXTVIEW;
  132.       return;
  133.    }
  134.  
  135.    if (self.observer_status & OBSERVER_TOGGLE_NOCLIP) {
  136.       if (self.movetype == MOVETYPE_FLY) {
  137.          self.movetype = MOVETYPE_NOCLIP;
  138.          sprint(self,"noclip on\n");
  139.       } else {
  140.          self.movetype = MOVETYPE_FLY;
  141.          sprint(self,"noclip off\n");
  142.       }
  143.       self.observer_status = self.observer_status - OBSERVER_TOGGLE_NOCLIP;
  144.    }
  145.  
  146.    if (self.button0) {
  147.       self.observer_status = OBSERVER_BUTTON0;
  148.       return;
  149.    }
  150.    else if (self.button1) {
  151.       self.observer_status = 0;
  152.       return;
  153.    }
  154.    else if (self.button2) {
  155.       self.observer_status = OBSERVER_BUTTON2;
  156.       return;
  157.    }
  158.  
  159.    if (self.observer_status & OBSERVER_BUTTON0) {
  160.       self.observer_status = OBSERVER_NEXTVIEW;
  161.       return;
  162.    }
  163.  
  164.    if (self.observer_status & OBSERVER_BUTTON2) {
  165.       self.observer_status  = OBSERVER_RESPAWN;
  166.       return;
  167.    }
  168.  
  169.    if (self.observer_status & OBSERVER_RESPAWN) {
  170.       respawn();
  171.       // remove flag must be set after respawn()
  172.       PlayerStatusRemoveFlag(self,PLAYER_IS_OBSERVER);
  173.       return;
  174.    }
  175. };
  176.  
  177. float() ObserverDeathThink = 
  178. {
  179.    if (!USE_MODULE_OBSERVER) return(0);
  180.  
  181.    if (self.button0) {
  182.       self.observer_status = OBSERVER_BUTTON0;
  183.    }
  184.    else if (self.button1) {
  185.       self.observer_status = 0;
  186.    }
  187.    else if (self.button2) {
  188.       self.observer_status = OBSERVER_BUTTON2;
  189.    }
  190.    else if (self.observer_status & (OBSERVER_BUTTON0 | OBSERVER_BUTTON2)) {
  191.       if (self.observer_status & OBSERVER_BUTTON0) self.observer_status = OBSERVER_BECOME_OBSERVER;
  192.       else self.observer_status = 0;
  193.       respawn();
  194.    }
  195.    self.button0 = 0;
  196.    self.button1 = 0;
  197.    self.button2 = 0;
  198.    return(1);
  199. };
  200.  
  201. void(entity player) ObserverBecomeObserver =
  202. {
  203.    //dprint("ObserverBecomeObserver: executing\n");//#jp#(debug)
  204.  
  205.    player.armorvalue       = 0;
  206.    player.items            = 0;
  207.    player.health           = 999;
  208.    player.ammo_shells      = 0;
  209.    player.ammo_nails       = 0;
  210.    player.ammo_rockets     = 0;
  211.    player.ammo_cells       = 0;
  212.    player.weapon           = 0;
  213.    player.currentammo      = 1;
  214.    player.takedamage       = DAMAGE_NO;
  215.    player.solid            = SOLID_NOT;
  216.    player.movetype         = MOVETYPE_FLY;
  217.    player.deadflag         = DEAD_NO;
  218.  
  219.    setmodel (player, string_null);
  220.  
  221.    player.weaponmodel      = "";
  222.    player.weaponframe      = 0;
  223.  
  224.    player.observer_pos_num = 0;
  225.    player.observer_status  = 0;
  226.    player.observer_pos_num = 1 + random() * 4;
  227.    ObserverSetPlayerPos(player);
  228. };
  229.  
  230.  
  231. entity(entity player) ObserverFindPos =
  232. {
  233.    local entity spot;
  234.    local float cont;
  235.  
  236.    //dprint("ObserverFindPos: executing\n");
  237.  
  238.    cont = 1;
  239.    while (cont<3) {
  240.       if      (player.observer_pos_num <= 0)  player.observer_pos_num = 1;
  241.       else if (player.observer_pos_num >= 21) player.observer_pos_num = 1;
  242.  
  243.       if (player.observer_pos_num <= 5) {
  244.                                                         spot = find (world, classname, "info_intermission");
  245.          if (player.observer_pos_num >= 2 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  246.          if (player.observer_pos_num >= 3 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  247.          if (player.observer_pos_num >= 4 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  248.          if (!spot) player.observer_pos_num = 5;
  249.       }
  250.       if (player.observer_pos_num >= 5) {
  251.                                                         spot = find (world, classname, "info_player_deathmatch");
  252.          if (player.observer_pos_num >=  6 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  253.          if (player.observer_pos_num >=  7 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  254.          if (player.observer_pos_num >=  8 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  255.          if (player.observer_pos_num >=  9 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  256.          if (player.observer_pos_num >= 10 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  257.          if (player.observer_pos_num >= 11 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  258.          if (player.observer_pos_num >= 12 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  259.          if (player.observer_pos_num >= 13 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  260.          if (player.observer_pos_num >= 14 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  261.          if (player.observer_pos_num >= 15 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  262.          if (player.observer_pos_num >= 16 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  263.          if (player.observer_pos_num >= 17 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  264.          if (player.observer_pos_num >= 18 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  265.          if (player.observer_pos_num >= 19 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  266.          if (player.observer_pos_num >= 20 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  267.          if (!spot) player.observer_pos_num = 21;
  268.       }
  269.       if (player.observer_pos_num >= 21) {
  270.             spot = find (world, classname, "info_player_start");
  271.             player.observer_pos_num = 21;
  272.       }
  273.       if (!spot) {
  274.          player.observer_pos_num = 0;
  275.       } else {
  276.          cont = 10;
  277.       }
  278.       cont = cont + 1;
  279.    }
  280.    if (!spot) error ("ObserverFindPos: could not find start pos");
  281.    return spot;
  282. };
  283.  
  284. void(entity player) ObserverSetPlayerPos =
  285. {
  286.    local entity pos;
  287.  
  288.    //dprint("ObserverSetPlayerPos: executing\n");//#jp#(debug)
  289.  
  290.    pos = ObserverFindPos(player);
  291.  
  292.    player.angles        = player.v_angle = pos.mangle;
  293.    player.fixangle      = TRUE;         // turn this way immediately
  294.    player.view_ofs      = '0 0 12'; // must be != '0 0 0'
  295.    player.velocity      = '0 0 0';
  296.  
  297.    makevectors (player.angles);
  298.    setsize (player, '-12  -12 -12', '12 12 12');
  299.    // setsize (player, VEC_HULL_MIN, VEC_HULL_MAX);
  300.    // player.view_ofs = '0 0 22';
  301.  
  302.    // avoid stuck observers for intermission spots 
  303.    if (player.observer_pos_num <=4) setorigin (player, pos.origin + '0 0 -60');
  304.    else                             setorigin (player, pos.origin);
  305. };
  306.  
  307. void(entity player) ObserverNoclip =
  308. {
  309.    if (!USE_MODULE_OBSERVER) return;
  310.  
  311.    player.observer_status = player.observer_status | OBSERVER_TOGGLE_NOCLIP;
  312. };
  313.  
  314. void(entity player,entity door) ObserverTeleportThroughDoor =
  315. {
  316.    local entity d,d_master;
  317.    local vector dmin,dmax;
  318.  
  319.    d_master = d = door.owner;
  320.    if (d_master) {
  321.       dmin = d_master.absmin;
  322.       dmax = d_master.absmax;
  323.    } else { 
  324.       dmin = dmax = '0 0 0'; 
  325.    }
  326.    if (dmin != dmax) {
  327.       // regular doors
  328.       if (d_master.state != STATE_BOTTOM) return;
  329.       do {
  330.          // dprint (vtos(d.absmin)); dprint (" "); dprint (vtos(d.absmax)); dprint ("\n");
  331.          if (d.absmin_x < dmin_x) { dmin_x = d.absmin_x; }
  332.          if (d.absmax_x > dmax_x) { dmax_x = d.absmax_x; }
  333.          if (d.absmin_y < dmin_y) { dmin_y = d.absmin_y; }
  334.          if (d.absmax_y > dmax_y) { dmax_y = d.absmax_y; }
  335.          if (d.absmin_z < dmin_z) { dmin_z = d.absmin_z; }
  336.          if (d.absmax_z > dmax_z) { dmax_z = d.absmax_z; }
  337.          d = d.enemy; // next linked door;
  338.       } while ((d != d_master) && (d != world));
  339.    }
  340.    else {
  341.       // secret doors
  342.       // we ignore these currently
  343.       return;
  344.    }
  345.  
  346.    {
  347.       local float is_x,is_y,is_z,set;
  348.       local vector dir,or;
  349.       set = is_x = is_y = is_z = FALSE;
  350.       or = player.origin;
  351.       if (dmin_x + 15 < player.absmin_x && player.absmax_x < dmax_x - 15) is_x = TRUE;
  352.       if (dmin_y + 15 < player.absmin_y && player.absmax_y < dmax_y - 15) is_y = TRUE;
  353.       if (dmin_z + 15 < player.absmin_z && player.absmax_z < dmax_z - 15) is_z = TRUE;
  354.       // dprint("doors:  "); dprint (vtos(dmin)); dprint (" "); dprint (vtos(dmax)); dprint ("\n");
  355.       // dprint("player: "); dprint (vtos(player.absmin)); dprint (" "); dprint (vtos(player.absmax)); dprint ("\n");
  356.       if (is_x && is_y) {
  357.          // dprint("door is in xy plane\n");
  358.          if      (or_z < dmin_z) { dir = '0 0  1'; or_z = dmax_z + 25; }
  359.          else if (or_z > dmax_z) { dir = '0 0 -1'; or_z = dmin_z - 25; }
  360.          set = TRUE;
  361.       }
  362.       else if (is_x && is_z) {
  363.          // dprint("door is in xz plane\n");
  364.          if      (or_y < dmin_y) { dir = '0  1 0'; or_y = dmax_y + 25; }
  365.          else if (or_y > dmax_y) { dir = '0 -1 0'; or_y = dmin_y - 25; }
  366.          set = TRUE;
  367.       }
  368.       else if (is_y && is_z) {
  369.          // dprint("door is in yz plane\n");
  370.          if      (or_x < dmin_x) { dir = ' 1 0 0'; or_x = dmax_x + 25; }
  371.          else if (or_x > dmax_x) { dir = '-1 0 0'; or_x = dmin_x - 25; }
  372.          set = TRUE;
  373.       }
  374.       if (set) { 
  375.          local vector v;
  376.          v =  normalize(player.velocity);
  377.          if (dir * v < 0.5) return;
  378.          player.origin = or;
  379.          setorigin (player, player.origin);
  380.       }
  381.    }
  382. };
  383.  
  384. void(entity player,entity tele) ObserverTeleportThroughTeleporter =
  385. {
  386.  
  387.    {
  388.       local vector v1,v2;
  389.       v1 = ((tele.absmax + tele.absmin) * 0.5) - player.origin; normalize(v1);
  390.       v2 = player.velocity; normalize(v2);
  391.       if (v1 * v2 <= 0.1) return;
  392.    }
  393.  
  394.    local entity targ;
  395.    targ = find (world, targetname, tele.target);
  396.    if (!targ) objerror ("ObserverTeleportThroughTeleporter: couldn't find teleporter target");
  397.    makevectors (targ.mangle);
  398.    setorigin (player, targ.origin);
  399.    player.angles = targ.mangle;
  400.    player.fixangle = TRUE; // turn this way immediately
  401.    player.teleport_time = time + 0.7;
  402.    player.velocity = v_forward * 300;
  403.    // player.flags = player.flags - player.flags & FL_ONGROUND;
  404. };
  405.  
  406.  
  407.